import axios, { AxiosRequestConfig, AxiosResponse, AxiosError } from "axios";
import { ToastService, DefaultToastService } from './ToastService'; // 导入 ToastService 接口 ToastService 实现
import qs from 'qs';

export type Response<T> =
  | {
    data: T;
    success: true;
    errorCode?: string;
    errorMessage?: string;
  }
  | {
    data?: T;
    success: false;
    errorCode: number;
    errorMessage: string;
  };

type ExtractKeys<T extends string> =
  T extends `${string}{${infer Key}}${infer Rest}`
  ? Key | ExtractKeys<Rest>
  : never;

type PathVariables<T extends string> = ExtractKeys<T> extends never
  ? Record<string, string | number>
  : Record<ExtractKeys<T>, string | number>;

type RequestConfig<
  D extends object,
  Q extends object,
  U extends string,
  P = PathVariables<U>
> = Omit<AxiosRequestConfig<D>, "url" | "params"> & {
  /**
   * @example '/api/:id' => pathVariables: { id: "1" }
   * @example '/api/:id/:name' => pathVariables: { id: "1", name: "2" }
   */
  url: U;
  ignoreAuth?: boolean; //不為true時 header需附帶Authentication value為token
  silentError?: boolean;
  throwError?: boolean;
  params?: Q;
  /**
   * @example '/api/:id' => { id: "1" }
   * @example '/api/:id/:name' => { id: "1", name: "2" }
   */
  pathVariables?: P;
  toastService?: ToastService; // 可选的 ToastService 实现
};

export interface Request {
  <
    T,
    D extends object = any,
    Q extends object = any,
    U extends string = string,
    P = PathVariables<U>
  >(
    args: RequestConfig<D, Q, U, P>
  ): Promise<Response<T>>;
}

const request: Request = async <
  T = any,
  D extends object = any,
  Q extends object = any,
  U extends string = string,
  P = PathVariables<U>
>(
  args: RequestConfig<D, Q, U, P>
): Promise<Response<T>> => {
  const { url, ignoreAuth, silentError, throwError, params, pathVariables, toastService = new DefaultToastService(), ...axiosConfig } = args;

  // 处理路径变量
  let finalUrl: U = url;
  if (pathVariables) {
    finalUrl = qs.stringify(params)
  }

  // 添加认证头
  if (!ignoreAuth) {
    axiosConfig.headers = {
      ...axiosConfig.headers,
      Authorization: `Bearer ${process.env.TOKEN || ''}`, // 从环境变量或其他地方获取 token
    };
  }

  try {
    const response: AxiosResponse<T> = await axios({
      ...axiosConfig,
      url: finalUrl,
      params,
    });

    return {
      data: response.data,
      success: true,
    };
  } catch (error: unknown) {
    const axiosError = error as AxiosError;

    if (silentError) {
      console.error('Silent Error:', axiosError.message);
    } else {
      console.error('Error:', axiosError.message);

      // 使用提供的 ToastService 显示错误消息
      toastService.show(axiosError.message, 'error');
    }

    if (throwError) {
      throw new Error(axiosError.message);
    }

    return {
      success: false,
      errorCode: axiosError.response?.status || 500,
      errorMessage: axiosError.message,
    };
  }
};

export default request;


